package com.liurong.util;

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.springframework.beans.factory.InitializingBean;

/**
 * 如果连续五次输错密码将锁定30分钟
 * 
 * @author lr
 * 
 */
public class RetryLimitCredentailMatcher extends HashedCredentialsMatcher
		implements InitializingBean {
	private Logger logger = Logger.getLogger(RetryLimitCredentailMatcher.class);

	/**
	 * 缓存管理器
	 */
	private CacheManager cacheManager;
	/**
	 * 缓存名字
	 */
	private String retryLimitCacheName;
	/**
	 * 重复输错密码的缓存
	 */
	private Cache<String, AtomicInteger> passwordRetryCache;

	public void setCacheManager(CacheManager cacheManager) {
		this.cacheManager = cacheManager;
	}

	public void setRetryLimitCacheName(String retryLimitCacheName) {
		this.retryLimitCacheName = retryLimitCacheName;
	}

	@Override
	public boolean doCredentialsMatch(AuthenticationToken token,
			AuthenticationInfo info) {
		String username = (String) token.getPrincipal();
		
		AtomicInteger retryCount = passwordRetryCache.get(username);
		if (retryCount == null) {
			retryCount = new AtomicInteger(0);
			passwordRetryCache.put(username, retryCount);
		}
		
		if (retryCount.incrementAndGet() > 2) {
			logger.warn(username + "连续输错了五次将锁定半个小时！");
			throw new ExcessiveAttemptsException(username + "连续输错了五次将锁定半个小时！");
		}
		
		boolean match = super.doCredentialsMatch(token, info);
		
		if (match) {
			passwordRetryCache.remove(username);
		}
		
		return match;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		this.passwordRetryCache = this.cacheManager.getCache(retryLimitCacheName);
	}

}
